package com.audaque.springboot.foshanupload.web.docdemo.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.audaque.springboot.foshanupload.core.model.qo.page.Page;
import com.audaque.springboot.foshanupload.web.util.HttpResponseUtils;
import com.audaque.springboot.foshanupload.core.util.WebFilenameUtils;
import com.audaque.springboot.foshanupload.web.docdemo.model.bo.AlarmInstanceBo;
import com.audaque.springboot.foshanupload.web.docdemo.model.req.AlarmInstanceReq;
import com.audaque.springboot.foshanupload.web.docdemo.model.rsp.AlarmInstanceRsp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


/**
 * <p>
 * 行为告警实例 前端控制器
 * </p>
 *
 * @author zgb
 * @since 2023-04-23
 */
@RestController
@Slf4j
@Api(value = "ZipEasyExcel 前端控制器")

@RequestMapping("/zipEasyExcel")
public class ZipEasyExcelController {

    //excel的sheet最大行数
    /**+
     * Excel 2003版：zhi列数dao最大256(IV，2的8次方)列，行数最大65536(2的16次方)行；
     * Excel 2007版：列数最大16384(XFD，2的14次方)，行数最大1048576(2的20次方)；
     * Excel 2013版：列数最大16384(XFD，2的14次方)，行数最大1048576(2的20次方)；
     */
    private Integer excelExportSize=50000;
    //分页分批导出最大批量
    private Integer pageExportSize=100;


    @PostMapping("exportExcel")
    @ApiOperation(value = "导出excel")
    public void export(@RequestBody AlarmInstanceReq req, HttpServletResponse response) throws Exception {
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Long count = 0L;
        //iAlarmInstanceService.count(req);
        if (count == 0) {
            return;
        }
        long excelNum = count / excelExportSize;
        if (count % excelExportSize != 0) {
            excelNum++;
        }


        List<Integer> list = new ArrayList<>();
        for (long l = 1; l <= excelNum; l++) {
            long startRow = (l - 1) * excelExportSize;
            int i = Integer.parseInt(Long.toString(startRow));
            list.add(i);
        }

        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // 获取输出流
        BufferedOutputStream bos = null;
        ZipOutputStream out = null;
        try {
            bos = new BufferedOutputStream(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {

            HttpResponseUtils.writeHeader(response, HttpHeaders.CONTENT_DISPOSITION,
                    WebFilenameUtils.disposition("文档.zip"));

            response.setContentType("application/x-msdownload;charset=UTF-8");
            response.setCharacterEncoding("utf-8");

            out = new ZipOutputStream(bos);

            //++++++++++++++++++++++++++++++++++++++
            for (Integer startRow : list) {

                ExcelWriter build = EasyExcel.write(response.getOutputStream(), AlarmInstanceBo.class).build();
                WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();

                req.setLimit(pageExportSize);
                req.setOffset(startRow);

                do {
                    Page<AlarmInstanceRsp> alarmInstanceRspPage = null;
                    //alarmInstanceRspPage = iAlarmInstanceService.page(req, false);

                    List<AlarmInstanceRsp> records = alarmInstanceRspPage.getRecords();
                    List<AlarmInstanceBo> alarmInstanceBos = new ArrayList<>();
                    for (AlarmInstanceRsp alarmInstanceRsp : records) {
                        AlarmInstanceBo alarmInstanceBo = new AlarmInstanceBo();
                        alarmInstanceBos.add(alarmInstanceBo);
                    }
                    build.write(alarmInstanceBos,
                            writeSheet);

                    startRow = startRow + pageExportSize;


                } while (startRow <= count);


                // 创建一个zip实体，其实就是表示压缩文件里的一个文件
                ZipEntry zipEntry = new ZipEntry("表格" + startRow + ".xlsx");

                // 把这个zip实体添加到压缩流中
                out.putNextEntry(zipEntry);

                // Workbook这是poi里的一个东西，具体的可以自己百度看看什么意思
                Workbook workbook = build.writeContext().writeWorkbookHolder().getWorkbook();

                // 把当前的内容写到zip流里面
                workbook.write(out);
            }

            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            log.debug("压缩完成");
        } catch (Exception e) {
            log.error("导出失败：{}", e.getMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }

            } catch (IOException e) {
                log.error("导出失败：{}", e.getMessage());
            }
            try {
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                log.error("导出失败：{}", e.getMessage());
            }
        }


    }


}
